home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Very Best of Atari Inside
/
The Very Best of Atari Inside 1.iso
/
sharew
/
accs
/
ud_gag
/
ud.src
< prev
Wrap
Text File
|
1985-07-19
|
7KB
|
281 lines
Just when you thought it was safe to turn your monitor rightside-up...
Here are the sources and uuencoded binary to a new version of my
silly upside down desk accessory. This one refreshes the screen at
more than 10 Hz when there is little change between refreshes.
It keeps checksums on 32 byte blocks of the screen and reverses the
changed blocks.
I promise not to post any more of these. Honest.
What do you mean, pointless?
Jan Gray
ud.c:
------------------
/*
* Upside-down DA, v.2 ...a somewhat less disappointing experiment
*
* Jan Gray 1986
*
* link: accstart,ud,flip,aesbind,osbind
*/
#include "gemdefs.h"
#include "osbind.h"
#define NULL 0
#define SCR_BYTES 32000L
#define SCR_ALIGN 512L /* must page align screen */
#define Supexec(code) xbios(38, code)
typedef unsigned char Byte; /* must be unsigned! */
long Chksums[32000/32];
Byte RevBytes[256];
Byte *RealScreen; /* real screen address */
Byte *FlipScreen; /* flipped screen address */
Byte *Phys; /* passed to setPhysBase() */
setPhysBase();
main()
{
extern int gl_apid;
char menuName[20];
int menuID;
int event;
int msg[8];
int ret;
appl_init();
buildRevBytes();
zapChksums();
RealScreen = Physbase();
FlipScreen = (Byte *)((Malloc(SCR_BYTES + SCR_ALIGN) + (SCR_ALIGN-1))
& ~(SCR_ALIGN-1));
menuName[0] = NULL;
menuID = menu_register(gl_apid, menuName);
for (;;) {
/* Wait for accessory open message */
strcpy(menuName, " Upside-down");
do {
event = evnt_mesag(msg);
} while (!(msg[0] == AC_OPEN && msg[4] == menuID));
/* Flip screen */
refreshFlip();
Phys = FlipScreen;
Supexec(setPhysBase);
/*
* Wait for accessory open or close message or 50 ms timeout.
*/
strcpy(menuName, " Rightside-up");
do {
event = evnt_multi(MU_MESAG | MU_TIMER,
0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
msg, 50, 0,
&ret, &ret, &ret, &ret, &ret, &ret);
if (event & MU_TIMER)
refreshFlip(); /* 20 to 150 ms */
} while (!((event & MU_MESAG) &&
(msg[0] == AC_OPEN && msg[4] == menuID ||
msg[0] == AC_CLOSE && msg[3] == menuID)));
/* Restore screen */
Phys = RealScreen;
Supexec(setPhysBase);
}
}
buildRevBytes() /* Build the byte reversal table */
{
register int i;
for (i = 0; i < 256; i++)
RevBytes[i] = ((i & 1) << 7) | ((i & 2) << 5) |
((i & 4) << 3) | ((i & 8) << 1) |
((i & 0x10) >> 1) | ((i & 0x20) >> 3) |
((i & 0x40) >> 5) | ((i & 0x80) >> 7);
}
zapChksums() /* Initialize the checksums to ff's */
{
register long *p;
register long ffffffff = 0xffffffffL;
for (p = Chksums; p < &Chksums[32000/32]; ) {
*p++ = ffffffff;
*p++ = ffffffff;
*p++ = ffffffff;
*p++ = ffffffff;
}
}
#define VBASE_HIGH (Byte *)0xff8201L
#define VBASE_LOW (Byte *)0xff8203L
/*
* setPhysBase -- set the physical screen to Phys. I don't use Setscreen()
* because it seems to clear the old logical screen...I don't want the
* ST to know that anything funny is going on, just to go merrily on its
* way writing to what it thinks is the physical screen...
*/
setPhysBase()
{
*VBASE_HIGH = (Byte)((unsigned long)Phys >> 16);
*VBASE_LOW = (Byte)((unsigned long)Phys >> 8);
}
/* Writing strcpy here saves us from linking with gemlib */
strcpy(dst, src)
register char *dst;
register char *src;
{
while (*dst++ = *src++)
;
}
----------------------
flip.s:
----------------------
*
* flip.s
*
* Assembler _refreshFlip.
*
* Reverse the real screen onto the flip screen. Rather than reversing
* every byte every time called (which is slow -- about 120 ms per call),
* we reverse only those bytes which have changed since the last call.
*
* Instead of saving yet another copy of the screen, we keep a longword
* checksum for each block of 32 bytes. If a new checksum differs, we save
* it away and reverse that 32 byte block.
*
* Since the screen changes little between calls, this is a big win, reducing
* the average time spent here from about 120 to 20 ms per call.
*
*
* Registers used
* a5 - real screen
* a4 - flip screen start
* a3 - flip screen
* a2 - reverse table
* a1 - checksum table
* a0 - constant 32
* d7-d0 - scratch
.globl _RealScreen
.globl _FlipScreen
.globl _RevBytes
.globl _Chksums
.text
.globl _refreshFlip
_refreshFlip:
link a6,#0
movem.l d0-d7/a0-a5,-(sp)
move.l _RealScreen,a5
move.l _FlipScreen,a4
move.l a4,a3
add.l #32000,a3 * a3 = end of FlipScreen
move.l #_RevBytes,a2
move.l #_Chksums,a1
move.l #32,a0
loop:
movem.l (a5)+,d0-d7 * fetch 32 bytes
add.l d1,d0 * compute new checksum
add.l d2,d0
add.l d3,d0
add.l d4,d0
add.l d5,d0
add.l d6,d0
add.l d7,d0
cmp.l (a1)+,d0 * compare against old checksum
bne rev * reverse line if different
sub.l a0,a3 * skip 32 bytes on flip screen
loop1:
cmp.l a4,a3 * done?
bcc loop
movem.l (sp)+,d0-d7/a0-a5
unlk a6
rts
rev:
move.l d0,-4(a1) * differs; save new checksum
sub.l a0,a5 * adjust a5 to front of 32 bytes
moveq.l #0,d0 * load upper byte with 0
move.b (a5)+,d0 * copy real byte through byte-
move.b 0(a2,d0.w),-(a3) * reversal table to flip screen
move.b (a5)+,d0 * likewise for 31 bytes
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
move.b (a5)+,d0
move.b 0(a2,d0.w),-(a3)
bra loop1 * continue
O.SNG to Àע: /ÇSTPAT.PRG ⇩¬♪t O SUNNING.TNY